﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace MUtil
{
    public delegate void CallBack();
    public delegate void CallBack<T>(T t);
    public delegate void CallBack<T, D>(T t, D d);
    public delegate void CallBack<T, D, U>(T t, D d, U u);

    public delegate T FuncCallBack<T>();
    public delegate T FuncCallBack<T, D>(D t);
    public delegate T FuncCallBack<T, D, U>(D t, U d);
    public delegate T FuncCallBack<T, D, U, V>(D d, U u, V v);
    public delegate T FuncCallBack<T, D, U, V, W>(D d, U u, V v, W w);

    public class EventManager
    {
        public static Dictionary<string, List<Delegate>> eventTable = new Dictionary<string, List<Delegate>>();


        static void OnListenerAdding(string eventkey, Delegate listenerDelegate)
        {
            if (!eventTable.ContainsKey(eventkey))
            {
                eventTable.Add(eventkey, new List<Delegate>());
            }
        }
        public static void AddListener(string eventtype, CallBack handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }

        public static void RemoveAllListener()
        {
            eventTable.Clear();
        }

        public static void RemoveListener(string eventtype)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                eventTable.Remove(eventtype);
            }
        }

        public static void RemoveListener(string eventtype, CallBack handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }  
            }
        }

        public static void RemoveListener<T>(string eventtype, CallBack<T> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T,D>(string eventtype, CallBack<T,D> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T, D, U>(string eventtype, CallBack<T, D, U> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

      

        public static void AddListener<T>(string eventtype, CallBack<T> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }
        public static void AddListener<T, D>(string eventtype, CallBack<T, D> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }
        public static void AddListener<T, D, U>(string eventtype, CallBack<T, D, U> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }
        static void OnBroadcast(string eventtype)
        {
            if (!eventTable.ContainsKey(eventtype))
            {
                Debug.LogError("不包含此监听");
                return;
            }
        }

        public static void Broadcast(string eventtype)
        {
            OnBroadcast(eventtype);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                        ((CallBack)eventTable[eventtype][i]).Invoke();
                }
            }
        }
        public static void Broadcast<T>(string eventtype, T t)
        {
            OnBroadcast(eventtype);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                        ((CallBack<T>)eventTable[eventtype][i]).Invoke(t);
                }
            }
        }
        public static void Broadcast<T, D>(string eventtype, T t, D d)
        {
            OnBroadcast(eventtype);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                        ((CallBack<T, D>)eventTable[eventtype][i]).Invoke(t, d);
                }
            }
        }
        public static void Broadcast<T, D, U>(string eventtype, T t, D d, U u)
        {
            OnBroadcast(eventtype);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                        ((CallBack<T, D, U>)eventTable[eventtype][i]).Invoke(t, d, u);
                }
            }
        }
        //==========================  上边是无返回值，下边是带返回值  ================================

        public static void AddListener<T>(string eventtype, FuncCallBack<T> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }

        public static void AddListener<T, D>(string eventtype, FuncCallBack<T, D> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }
        public static void AddListener<T, D, U>(string eventtype, FuncCallBack<T, D, U> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }
        public static void AddListener<T, D, U, V>(string eventtype, FuncCallBack<T, D, U, V> handler)
        {
            OnListenerAdding(eventtype, handler);
            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }

        public static void AddListener<T, D, U, V, W>(string eventtype, FuncCallBack<T, D, U, V, W> handler)
        {
            OnListenerAdding(eventtype, handler);

            if (!eventTable[eventtype].Contains(handler))
            {
                eventTable[eventtype].Add(handler);
            }
        }


        public static void RemoveListener<T>(string eventtype, FuncCallBack<T> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T, D>(string eventtype, FuncCallBack<T, D> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T, D, U>(string eventtype, FuncCallBack<T, D, U> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T, D, U,V>(string eventtype, FuncCallBack<T, D, U,V> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }

        public static void RemoveListener<T, D, U, V,W>(string eventtype, FuncCallBack<T, D, U, V,W> handler)
        {
            if (eventTable.ContainsKey(eventtype))
            {
                if (eventTable[eventtype].Contains(handler))
                {
                    eventTable[eventtype].Remove(handler);
                }
            }
        }










        public static T Broadcast<T>(string eventtype)
        {
            OnBroadcast(eventtype);
            T t = default(T);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                    {
                        t = ((FuncCallBack<T>)eventTable[eventtype][i]).Invoke();
                    }
                }
            }
            return t;
        }
        public static T Broadcast<T, D>(string eventtype, D d)
        {
            OnBroadcast(eventtype);
            T t = default(T);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                    {
                        t = ((FuncCallBack<T, D>)eventTable[eventtype][i]).Invoke(d);
                    }
                }
            }
            return t;
        }
        public static T Broadcast<T, D, U>(string eventtype, D d, U u)
        {
            OnBroadcast(eventtype);
            T t = default(T);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                    {
                        t = ((FuncCallBack<T, D, U>)eventTable[eventtype][i]).Invoke(d, u);
                    }
                }
            }
            return t;
        }

        public static T Broadcast<T, D, U, V>(string eventtype, D d, U u, V v)
        {
            OnBroadcast(eventtype);
            T t = default(T);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                    {
                        t = ((FuncCallBack<T, D, U, V>)eventTable[eventtype][i]).Invoke(d, u, v);
                    }
                }
            }
            return t;
        }

        public static T Broadcast<T, D, U, V, W>(string eventtype, D d, U u, V v, W w)
        {
            OnBroadcast(eventtype);
            T t = default(T);
            if (eventTable.ContainsKey(eventtype))
            {
                for (int i = 0; i < eventTable[eventtype].Count; i++)
                {
                    if (eventTable[eventtype][i] != null)
                    {
                        t = ((FuncCallBack<T, D, U, V, W>)eventTable[eventtype][i]).Invoke(d, u, v, w);
                    }
                }
            }
            return t;
        }
    }
}
